package com.navidove.web.manager.ctrl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.navidove.appspotlight.model.bo.AppDevice;
import com.navidove.appspotlight.model.bo.AppDevice.DeviceType;
import com.navidove.appspotlight.model.bo.AppDictionary;
import com.navidove.appspotlight.model.bo.AppItem;
import com.navidove.appspotlight.model.bo.SysImage;
import com.navidove.appspotlight.model.dao.AppDictionaryDao;
import com.navidove.appspotlight.model.dao.AppItemDao;
import com.navidove.appspotlight.model.dao.SysImageDao;
import com.navidove.appspotlight.model.service.AppDictionaryService;
import com.navidove.appspotlight.model.service.AppItemService;
import com.navidove.commons.exception.DataDuplicatedException;
import com.navidove.commons.utils.DaoPropertyEditor;
import com.navidove.commons.utils.DateUtils;
import com.navidove.commons.utils.EnhanceEnumPropertyEditor;
import com.navidove.commons.utils.I18NUtil;


@Controller
@RequestMapping("/app/appItem")
public class AppItemEditCtrl {

	protected final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
	
	@Autowired
	private AppItemService appItemService;
	
	@Autowired
	private AppDictionaryService appDictionaryService;
	
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtils.DEFAULT_DATE_PATTERN);
        dateFormat.setLenient(false);        
        binder.registerCustomEditor(AppDictionary.class, DaoPropertyEditor.getInstance(AppDictionaryDao.class));
        binder.registerCustomEditor(AppItem.class, DaoPropertyEditor.getInstance(AppItemDao.class));
        binder.registerCustomEditor(SysImage.class, DaoPropertyEditor.getInstance(SysImageDao.class));
        binder.registerCustomEditor(DeviceType.class, new EnhanceEnumPropertyEditor(DeviceType.class));
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
    }
    
    @ModelAttribute
    public void reset(Model model, @RequestParam(value="id", required=false) Long id) {        

        AppItem appItem = null;
        if (id == null) {
        	appItem = new AppItem();
        	appItem.setEnable(Boolean.TRUE);
        } else {
        	appItem = appItemService.getAppItem(id);
        }
        model.addAttribute("appItem", appItem);  
        
        Map<String, AppDevice> map = new HashMap<String, AppDevice>();
        for (AppDevice dev : appItemService.getAppDeviceList(id)) {
        	map.put(dev.getDeviceType().getCode(), dev);
        }
        
        DeviceType[] deviceTypes = AppDevice.DeviceType.values();
        model.addAttribute("deviceTypes", deviceTypes);
        for (DeviceType t : deviceTypes) {
        	AppDevice dev = map.get(t.getCode());
        	if (dev == null) dev = new AppDevice();
        	dev.setAppItem(appItem);
        	model.addAttribute(t.getCode(), dev);
        }
    }
    
    
    @RequestMapping("/add")
    public String add(Model model) {
        List<AppDictionary> sourceList = appDictionaryService.getAppDictionaryList(AppDictionary.DICTIONARY_TYPE_SOURCE);
        List<AppDictionary> categoryList = appDictionaryService.getAppDictionaryList(AppDictionary.DICTIONARY_TYPE_CATEGORY);
        
        model.addAttribute("sourceList", sourceList);
        model.addAttribute("categoryList", categoryList);
        
        return "/app/appItem_edit";
    }
    
    @RequestMapping("/edit")
    public String edit(Model model) {
        List<AppDictionary> sourceList = appDictionaryService.getAppDictionaryList(AppDictionary.DICTIONARY_TYPE_SOURCE);
        List<AppDictionary> categoryList = appDictionaryService.getAppDictionaryList(AppDictionary.DICTIONARY_TYPE_CATEGORY);
        
        model.addAttribute("sourceList", sourceList);
        model.addAttribute("categoryList", categoryList);
              
        return "/app/appItem_edit";
    }
    
    @ResponseBody
    @RequestMapping("/save")
    public Map<String, Object> save(Model model, @ModelAttribute("appItem") AppItem appItem) {

        String success = I18NUtil.getMsg("dialog.message.data.param.success", I18NUtil.getMsg("button.save"));
        String failure = I18NUtil.getMsg("dialog.message.data.param.failure", I18NUtil.getMsg("button.save"));
        
        Map<String, Object> rtnVal = new HashMap<String, Object>();        
 
        try {
            appItemService.saveAppItem(appItem);
            rtnVal.put("message", success);
            rtnVal.put("success", Boolean.TRUE);
            rtnVal.put("data", appItem.getId());
        } catch (DataDuplicatedException e) {
            logger.error(e.getMessage(),e);
            rtnVal.put("message", I18NUtil.getMsg("dialog.message.param.not.duplicated",
                    I18NUtil.getMsg("bo.AppItem.appName")));
            rtnVal.put("success", Boolean.FALSE);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            rtnVal.put("message", failure);
            rtnVal.put("success", Boolean.FALSE);
        }

        return rtnVal;
    } 
    
    @ResponseBody
    @RequestMapping("/delete")
    public Map<String, Object> delete(Model model, @ModelAttribute("id") Long id) {

        String success = I18NUtil.getMsg("dialog.message.data.param.success", I18NUtil.getMsg("button.delete"));
        String failure = I18NUtil.getMsg("dialog.message.data.param.failure", I18NUtil.getMsg("button.delete"));
        
        Map<String, Object> rtnVal = new HashMap<String, Object>();        
 
        try {
            appItemService.deleteAppItem(id);
            rtnVal.put("message", success);
            rtnVal.put("success", Boolean.TRUE);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            rtnVal.put("message", failure);
            rtnVal.put("success", Boolean.FALSE);
        }

        return rtnVal;
    }    
    
    @ResponseBody
    @RequestMapping("/saveDevice")
    public Map<String, Object> saveDevice(Model model, 
    		@ModelAttribute AppDevice appDevice,
    		@RequestParam("qrcImageFile") MultipartFile qrcImageFile,
    		@RequestParam("iconImageFile") MultipartFile iconImageFile) {

        String success = I18NUtil.getMsg("dialog.message.data.param.success", I18NUtil.getMsg("button.save"));
        String failure = I18NUtil.getMsg("dialog.message.data.param.failure", I18NUtil.getMsg("button.save"));
        
        Map<String, Object> rtnVal = new HashMap<String, Object>();        
 
        try {
            appItemService.saveAppDevice(appDevice, qrcImageFile, iconImageFile);
            rtnVal.put("message", success);
            rtnVal.put("success", Boolean.TRUE);
            rtnVal.put("data", appDevice.getId());
        } catch (DataDuplicatedException e) {
            logger.error(e.getMessage(),e);
            rtnVal.put("message", I18NUtil.getMsg("dialog.message.param.not.duplicated",
                    I18NUtil.getMsg("bo.AppItem.appName")));
            rtnVal.put("success", Boolean.FALSE);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            rtnVal.put("message", failure);
            rtnVal.put("success", Boolean.FALSE);
        }

        return rtnVal;
    } 
    
    @ResponseBody
    @RequestMapping("/deleteDevice")
    public Map<String, Object> deleteDevice(Model model, 
    		@RequestParam ("appItem") AppItem appItem,
    		@RequestParam("deviceType") DeviceType deviceType) {

        String success = I18NUtil.getMsg("dialog.message.data.param.success", I18NUtil.getMsg("button.delete"));
        String failure = I18NUtil.getMsg("dialog.message.data.param.failure", I18NUtil.getMsg("button.delete"));
        
        Map<String, Object> rtnVal = new HashMap<String, Object>();        
 
        try {
            appItemService.deleteAppDevice(appItem.getId(), deviceType);
            rtnVal.put("message", success);
            rtnVal.put("success", Boolean.TRUE);
        } catch (DataDuplicatedException e) {
            logger.error(e.getMessage(),e);
            rtnVal.put("message", I18NUtil.getMsg("dialog.message.param.not.duplicated",
                    I18NUtil.getMsg("bo.AppItem.appName")));
            rtnVal.put("success", Boolean.FALSE);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            rtnVal.put("message", failure);
            rtnVal.put("success", Boolean.FALSE);
        }

        return rtnVal;
    }
}
